home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr48 / st4gw110.zip / STUB4GW.ASM < prev    next >
Assembly Source File  |  1994-12-29  |  10KB  |  524 lines

  1. ;
  2. ; Name:        Stub Loader for DOS4GW DOS Extender
  3. ; Version:    1.10
  4. ; Date:        Dec-29-1994
  5. ; Author:    Vladimir Arnost (QA-Software)  <xarnos00@dcse.fee.vutbr.cz>
  6. ; Compiler:    TASM 3.2
  7. ;
  8. ; History:
  9. ;   1.00  Dec-20-1994    Written
  10. ;   1.10  Dec-29-1994    Minor changes, model changed from small to tiny
  11. ;            Added quiet extender support
  12. ;            Fixed bug in PrepareParams
  13.  
  14. .8086
  15. .MODEL TINY, C
  16. LOCALS
  17. JUMPS
  18.  
  19. StackSize    EQU    128
  20.  
  21. CRLF        EQU    0Dh,0Ah
  22. EOL        EQU    '$'
  23. Environment    EQU    2Ch
  24. FCB1        EQU    5Ch
  25. FCB2        EQU    6Ch
  26. PSP_PARAMS    EQU    80h
  27. OFST        EQU    (WORD PTR 0)
  28. SEGM        EQU    (WORD PTR 2)
  29.  
  30. .CODE
  31.  
  32. IFDEF QUIET
  33.         db    'DOS/4GW STUB V1.10Q - Copyright 1994 QA-Software'
  34. ELSE
  35.         db    'DOS/4GW STUB V1.10 - Copyright 1994 QA-Software',0
  36. ENDIF
  37.  
  38. ;*** Main program
  39. Stub4GW        PROC    FAR
  40.         mov    dx,cs
  41.         mov    ds,dx
  42. ; CS - code segment
  43. ; DS - data segment (same as CS in Tiny model)
  44. ; ES - PSP segment
  45.         call    Check386
  46.         jnc    @@1
  47.         mov    dx,offset Msg_Need386
  48.         mov    al,0FFh
  49.         jmp    @@Error
  50. .386
  51. @@1:        mov    ax,es
  52.         mov    fs,ax
  53.         mov    gs,es:[Environment]    ; environment segment
  54.         mov    es,dx
  55. ; ES - data segment
  56. ; FS - PSP segment
  57. ; GS - environment segment
  58.         call    ReleaseMemory
  59.         call    FindDOS4GW
  60. ; DS:DX - DOS4GW path
  61.         call    PrepareParams
  62. ; ES:BX - parameters
  63. IFDEF QUIET
  64.         call    PrepareEnvironment
  65. ELSE
  66.         xor    ax,ax
  67. ENDIF
  68. ; AX - environment segment
  69.         call    Exec
  70. .8086
  71.         or    ax,ax
  72.         jnz    @@ExecError
  73. ; Get program exit code
  74.         mov    ah,4Dh
  75.         int    21h
  76. ; AL=exit code        
  77.         mov    ah,4Ch
  78.         int    21h            ; terminate
  79.  
  80.  
  81. @@ExecError:    mov    bx,offset Msg_ErrorCode
  82.         call    HexWord
  83.         mov    dx,offset Msg_Error
  84.         mov    al,0FEh
  85.  
  86. ; In:        DS:DX    error message
  87. ;        AL    return code
  88. @@Error:    push    ax
  89.         mov    ah,9
  90.         int    21h
  91.         pop    ax
  92.         mov    ah,4Ch
  93.         int    21h            ; terminate
  94. Stub4GW        ENDP
  95.  
  96.  
  97. ;*** Check presence of 386 or better processor
  98. ; In:        none
  99. ; Out:        AL=0,  CF=NC - 386 found
  100. ;        AL!=0, CF=CY - no 386
  101. ; Changes:    AH
  102. Check386    PROC
  103.         pushf
  104.         mov    ax,7000h
  105.         push    ax
  106.         popf
  107.         pushf
  108.         pop    ax
  109.         and    ax,07000h
  110.         jz    @@1            ; not found
  111.         mov    al,1            ; found 386
  112. @@1:        popf
  113.         sub    al,1
  114.         ret
  115. Check386    ENDP
  116.  
  117.  
  118. .386
  119. ;*** Shrink memory block used by the loader
  120. ReleaseMemory    PROC
  121.         USES    ES,BX
  122.         mov    bx,ss            ; Stack segment - end of pgm
  123.         add    bx,(StackSize+15)/16
  124.         mov    ax,fs            ; PSP segment - start of pgm
  125.         sub    bx,ax
  126.         mov    es,ax
  127.         mov    ah,4Ah
  128.         int    21h
  129.         ret
  130. ReleaseMemory    ENDP
  131.  
  132.  
  133. ;*** Find DOS4GW.EXE or DOS4G.EXE
  134. ; In:        none
  135. ; Out:        DS:DX    DOS4G[W] full path (if possible)
  136. ; Changes:    AX
  137. FindDOS4GW    PROC
  138. ; Try DOS4GPATH
  139.         mov    dx,offset EnvDOS4GPATH
  140.         call    FindProgram
  141.         jnc    @@Ret
  142. ; Try PATH
  143.         mov    dx,offset EnvPATH
  144.         call    FindProgram
  145.         jnc    @@Ret
  146. ; none found -- return current directory
  147.         mov    dx,offset DOS4GW_EXE
  148. @@Ret:        ret
  149. FindDOS4GW    ENDP
  150.  
  151.  
  152. ;*** Find DOS4GW.EXE or DOS4G.EXE using environment variable
  153. ; In:        DS:DX    Environment variable name
  154. ; Out:        CF=NC    found
  155. ;        CF=CY    not found
  156. ;        DS:DX    DOS4G[W] full path
  157. ; Changes:    AX
  158. FindProgram    PROC
  159.         USES    SI,DI,BX
  160. ; Read environment
  161.         mov    di,offset EnvBuffer
  162.         call    GetEnv
  163.         cmp    ax,0
  164.         jb    @@Ret
  165. ; Variable exists
  166.         mov    si,di
  167.         mov    di,offset DOS4GWpathName
  168.         mov    bx,offset DOS4GW_EXE
  169.         call    ScanPath
  170.         jnc    @@Ret
  171.         mov    bx,offset DOS4G_EXE
  172.         call    ScanPath
  173. @@Ret:        ret
  174. FindProgram    ENDP
  175.  
  176.  
  177. ;*** Get environment string
  178. ; In:        DS:DX    environment variable name (must be uppercase) LString
  179. ;        ES:DI    destination buffer
  180. ;        GS:0000    environment
  181. ; Out:        AX = -1    not found
  182. ;        otherwise AX contains length
  183. ;        [ES:DI]    filled
  184. GetEnv        PROC
  185.         USES    SI,DI,BX,CX
  186.         cld
  187.         mov    si,dx
  188.         lodsb
  189.         movzx    cx,al
  190.         jcxz    @@NotFound
  191. ;
  192.         mov    bx,-1        ; GS:BX - environment pointer
  193. @@Scan:        push    cx si
  194. @@1:        lodsb
  195.         inc    bx
  196.         cmp    al,gs:[bx]
  197.         loope    @@1
  198.         pop    si cx
  199.         jne    @@Next
  200.         inc    bx
  201.         cmp    BYTE PTR gs:[bx],'='
  202.         jne    @@Next
  203. ; found -- copy it to ES:DI
  204.         lea    cx,[bx+1]
  205. @@2:        inc    bx
  206.         mov    al,gs:[bx]
  207.         stosb
  208.         or    al,al
  209.         jnz    @@2
  210.         mov    ax,bx
  211.         sub    ax,cx
  212.         jmp    @@Ret
  213. ; skip to next
  214. @@Next:        xor    al,al
  215. @@3:        inc    bx
  216.         cmp    gs:[bx],al
  217.         jnz    @@3
  218.         cmp    gs:[bx+1],al
  219.         jnz    @@Scan
  220. ; variable not found
  221. @@NotFound:    mov    ax,-1        
  222. @@Ret:        ret
  223. GetEnv        ENDP
  224.  
  225.  
  226. ;*** Get program path from the environment
  227. ; In:        ES:DI    destination buffer
  228. ;        GS:0000    environment
  229. ; Out:        CX    length
  230. ;        [ES:DI]    filled
  231. GetPgmPath    PROC
  232.         USES    BX
  233.         cld
  234.         xor    bx,bx        ; GS:BX - environment pointer
  235.         xor    ax,ax
  236.         mov    cx,8000h
  237. @@1:        cmp    gs:[bx],ax
  238.         je    @@2
  239.         inc    bx
  240.         loop    @@1
  241.         jmp    @@Ret        ; not found - this should never happen
  242. ; found -- copy it to ES:DI
  243. @@2:        add    bx,4        ; skip zeros and count (1)
  244.         xor    cx,cx        ; CX - count
  245. @@3:        mov    al,gs:[bx]
  246.         inc    bx
  247.         inc    cx
  248.         stosb
  249.         or    al,al
  250.         jnz    @@3
  251.         dec    cx        ; CX=length of the pathname
  252. @@Ret:        ret
  253. GetPgmPath    ENDP
  254.  
  255.  
  256. ;*** Scan directories specified in form 'path1;path2;path3...' for filename
  257. ; In:        DS:BX    filename to be found
  258. ;        DS:SI    path
  259. ;        ES:DI    destination buffer for full filename
  260. ; Out:        CF=NC, AX=0    found
  261. ;        CF=CY, AX!=0    not found
  262. ;        ES:DX = ES:DI    full filename
  263. ScanPath    PROC
  264.         USES    BX,CX
  265.         cld
  266.         mov    dx,di
  267. @@Loop:        xor    ax,ax
  268. ; copy one element of path
  269. @@1:        lodsb
  270.         cmp    al,';'
  271.         je    @@2
  272.         or    al,al
  273.         je    @@2
  274.         stosb
  275.         inc    ah
  276.         jmp    @@1
  277. ; add backslash if necessary
  278. @@2:        mov    cx,ax            ; save last char
  279.         or    ah,ah
  280.         jz    @@3            ; AH=0 -- path element is empty
  281.         mov    al,es:[di-1]
  282.         cmp    al,'\'
  283.         je    @@3
  284.         cmp    al,':'
  285.         je    @@3
  286.         mov    al,'\'            ; append backslash
  287.         stosb
  288. ; add filename to path
  289. @@3:        push    si
  290.         mov    si,bx
  291. @@4:        lodsb
  292.         stosb
  293.         or    al,al
  294.         jnz    @@4        
  295.         pop    si
  296. ; DS:DX now contains full path
  297.         mov    ax,3D40h        ; open for reading, deny none
  298.         int    21h
  299.         jc    @@5            ; error -- file not found
  300. ; file exists, close its handle
  301.         mov    bx,ax
  302.         mov    ah,3Eh
  303.         int    21h
  304.         xor    ax,ax
  305.         jmp    @@Ret
  306. ;
  307. @@5:        mov    di,dx            ; DX=saved DI
  308.         or    cl,cl            ; CL=last char (00h or ';')
  309.         jnz    @@Loop
  310.         stc
  311. @@Ret:        ret
  312. ScanPath    ENDP
  313.  
  314.  
  315. ;*** Prepare program parameters
  316. ; In:        none
  317. ; Out:        ES:BX    parameters
  318. ; Changes:    AX
  319. PrepareParams    PROC
  320.         USES    SI,DI,CX
  321.         mov    di,offset EnvBuffer+1
  322.         call    GetPgmPath
  323.         dec    di
  324. ; add space if necessary
  325.         mov    si,PSP_PARAMS
  326.         lods    BYTE PTR fs:[si]
  327.         xor    ah,ah            ; AX=length of orig. params
  328.         or    ax,ax
  329.         jz    @@1
  330.         push    ax
  331.         mov    al,' '
  332.         cmp    BYTE PTR fs:[si],al
  333.         je    @@0
  334.         stosb
  335.         inc    cx
  336. @@0:        pop    ax
  337. ; add original parameters
  338. @@1:        mov    bx,7Eh            ; max. length of parameters
  339.         sub    bx,cx
  340.         xchg    bx,cx            ; BX=length so far
  341.         cmp    cx,ax            ; CX=remaining bytes
  342.         jbe    @@2
  343.         mov    cx,ax            ; CX=bytes to be copied
  344. @@2:        add    bx,cx            ; BX=total length
  345.         inc    cx            ; copy trailing CR
  346.         rep    movs BYTE PTR es:[di], fs:[si]
  347. ;
  348.         mov    al,bl
  349.         mov    bx,offset EnvBuffer
  350.         mov    [bx],al
  351.         ret
  352. PrepareParams    ENDP
  353.  
  354.  
  355. IFDEF QUIET
  356. ;*** Prepare program environment -- add string "DOS4G=QUIET"
  357. ; In:        GS:0000    environment
  358. ; Out:        AX    new environment segment
  359. PrepareEnvironment    PROC
  360.         USES    ES,BX,DI
  361.         mov    ax,gs
  362.         dec    ax
  363.         mov    es,ax
  364.         mov    bx,es:[3]        ; size of current environment
  365.         shl    bx,4
  366. ;
  367.         inc    ax
  368.         mov    es,ax
  369.         xor    ax,ax
  370.         xor    di,di
  371. @@1:        cmp    es:[di],al
  372.         je    @@2
  373.         mov    cx,8000H
  374.         repne    scasb
  375.         jmp    @@1
  376. ;
  377. @@2:        mov    ax,bx
  378.         sub    ax,di
  379.         cmp    ax,EnvDOS4G_Len+5
  380.         jge    @@3
  381. ; create new environment block
  382.         lea    bx,[di+EnvDOS4G_Len+5+15]
  383.         shr    bx,4
  384.         mov    ah,48h            ; allocate memory
  385.         int    21h
  386.         jc    @@Ret
  387.         push    si
  388.         mov    es,ax            ; ES - new environment segment
  389.         mov    cx,di            ; GS - old environment segment
  390.         xor    di,di
  391.         xor    si,si
  392.         rep    movs BYTE PTR es:[di], gs:[si]
  393.         pop    si
  394.         mov    bx,gs
  395.         mov    gs,ax            ; GS - new environment segment
  396.         mov    fs:[Environment],ax    ; update environment segment #
  397.         push    es
  398.         mov    es,bx
  399.         mov    ah,49H            ; free old environment block
  400.         int    21h
  401.         pop    es
  402. ; add string (destroying program load path)
  403. @@3:        mov    si,offset EnvDOS4G
  404.         mov    cx,EnvDOS4G_Len
  405.         rep    movsb
  406.         xor    ax,ax
  407.         stosb
  408.         stosw
  409.         stosw
  410. @@Ret:        mov    ax,gs
  411.         ret
  412. PrepareEnvironment    ENDP
  413. ENDIF
  414.  
  415.  
  416. ;*** Run program
  417. ; In:        DS:DX    complete filename (ASCIIZ)
  418. ;        ES:BX    parameters
  419. ;        AX    environment segment
  420. ; Out:        AX    exec code
  421. Exec        PROC
  422. ; Prepare environment
  423.         mov    EPB_Env,ax
  424. ; Prepare Parameters
  425.         mov    EPB_Param.Ofst,bx
  426.         mov    EPB_Param.Segm,es
  427. ; Prepare FCBs
  428.         mov    EPB_FCB1.Ofst,FCB1
  429.         mov    EPB_FCB1.Segm,fs        ; FS=PSP
  430.         mov    EPB_FCB2.Ofst,FCB2
  431.         mov    EPB_FCB2.Segm,fs
  432. ; Save stack
  433.         mov    SaveStack.Ofst,sp
  434.         mov    SaveStack.Segm,ss
  435. ; Execute
  436.         mov    bx,offset EPB
  437.         mov    ax,4B00h
  438.         int    21h
  439. ; Restore stack & segments
  440.         cli
  441.         jc    @@1
  442.         xor    ax,ax
  443. @@1:        mov    bx,cs
  444.         mov    ds,bx
  445.         mov    es,bx
  446.         lss    sp,SaveStack
  447.         sti
  448.         cld
  449.         ret
  450. Exec        ENDP
  451.  
  452.  
  453. ;*** Convert 16-bit register to 4 hex digits
  454. ; In:        AX    number
  455. ;        DS:BX    destination
  456. ; Out:        DS:BX    end of string
  457. ; Changes:    AX, BX
  458. HexWord        PROC
  459.         push    ax
  460.         mov    al,ah
  461.         call    HexByte
  462.         pop    ax
  463.  
  464. HexByte     PROC                ; AL --> Hex Ascii DS:BX
  465.         push    ax
  466.         shr    al,4
  467.         call    @@1
  468.         pop    ax
  469.         and    al,0fh
  470. @@1:        add    al,90h
  471.         daa
  472.         adc    al,40h
  473.         daa
  474.         mov    [bx],ax
  475.         inc    bx
  476.         ret
  477. HexByte     ENDP
  478. HexWord     ENDP
  479.  
  480. ;;        db    3 dup (0)    ; align manually
  481.  
  482. .DATA
  483.  
  484. Msg_Need386    db    'This program requires 386 or better processor',CRLF,EOL
  485. Msg_Error    db    'Can''t run DOS4GW.EXE. Error code '
  486. Msg_ErrorCode    db    '0000',CRLF,EOL
  487.  
  488. EnvDOS4GPATH    db    9,'DOS4GPATH'
  489. EnvPATH        db    4,'PATH'
  490.         db    0
  491.  
  492. DOS4GW_EXE    db    'DOS4GW.EXE',0
  493. DOS4G_EXE    db    'DOS4G.EXE',0
  494.  
  495. IFDEF QUIET
  496. EnvDOS4G    db    'DOS4G=QUIET',0
  497. EnvDOS4G_Len    = $ - EnvDOS4G
  498. ENDIF
  499.  
  500. ; align the file-length to be a multiple of 16
  501. IFDEF QUIET
  502.         db    9 dup (0)
  503. ELSE
  504.         db    13 dup (0)
  505. ENDIF
  506.  
  507.  
  508. .DATA?
  509.  
  510. SaveStack    dd    ?
  511.  
  512. EPB        LABEL    BYTE            ; EPB - Exec parameter block
  513. EPB_Env        dw    ?
  514. EPB_Param    dd    ?
  515. EPB_FCB1    dd    ?
  516. EPB_FCB2    dd    ?    
  517.  
  518. DOS4GWpathName    db    128 dup (?)
  519. EnvBuffer    db    128 dup (?)
  520.  
  521. .STACK    StackSize
  522.  
  523.         END    Stub4GW
  524.